平台 CLI 教程
本教程将引导您使用平台 CLI 构建、测试并将示例应用推送到 Zapier。我们将使用一个模拟 API 来处理食谱示例,但对于生产环境的 Zapier 应用,您应连接到真实的 API。
先决条件
-
您需要一个 Zapier 帐户。
-
您的开发环境需满足 运行平台 CLI 的要求,并安装正确的 Node.js 版本。
-
安装平台 CLI 工具:
# 全局安装 CLI
npm install -g zapier-platform-cli
要查看平台 CLI 中所有可用命令,请运行 zapier help
。
- 接下来,通过 CLI 进行身份验证。
# 使用部署密钥设置对 Zapier 平台的身份验证
zapier login
Zapier 会将您的部署密钥写入 ~/.zapierrc
文件。请妥善保管该文件,不要将其纳入源代码管理。
1. 开始一个集成
使用 init
命令设置 所需的结构。系统会显示可用模板列表供您选择。
# 创建一个目录,其中包含最小所需的文件,并选择一个模板
zapier init example-app --template minimal
# 进入新目录
cd example-app
在该目录中,您会看到几个文件。package.json
是典型 Node.js 应用的依赖文件,已预填充了一些依赖项,其中最重要的是 zapier-platform-core
,这是使您的应用与 Zapier 平台兼容的核心。还有一个 index.js
文件和一个测试目录(稍后详述)。在继续之前,请安装应用的依赖项:
npm install
index.js
index.js
是您的应用的入口点。这是平台用于理解您的应用如何与 Zapier 交互的地方。在您选择的代码编辑器中打开该目录。
您可能会在 index.js
中看到以下内容:
-
一个单一的
module.exports
定义,由 Zapier 解释。 -
triggers
用于描述从您的应用数据中触发的机制。 -
searches
用于描述在您的应用中查找数据的方式。 -
creates
用于描述在您的应用中创建数据的方式。 -
resources
是可选的,用于方便描述应用中的 CRUD-like 对象(请参阅 示例 resources 应用)。 -
beforeRequest
和afterResponse
是 HTTP 客户端的钩子,用于在每次调用中操作请求和响应。
2. 添加一个触发器
添加一个 触发器,配置为从模拟 API 中读取数据:
zapier scaffold trigger recipe
scaffold 会创建一个新文件 recipe.js
,位于 triggers
文件夹中。在构建自己的集成时,您可能会使用如 contact.js
、lead.js
或 order.js
这样的文件名。
打开 triggers/recipe.js
(由 zapier scaffold trigger recipe
创建的文件),并用以下内容替换:
const listRecipes = async (z, bundle) => {
const response = await z.request("http://57b20fb546b57d1100a3c405.mockapi.io/api/recipes");
return response.data;
};
module.exports = {
key: "recipe",
noun: "Recipe",
display: {
label: "New Recipe",
description: "Triggers when a new recipe is created.",
},
operation: {
perform: listRecipes,
sample: {
id: 1,
createdAt: 1472069465,
name: "Best Spaghetti Ever",
authorId: 1,
directions: "1. Boil Noodles\n2. Serve with sauce",
style: "italian",
},
},
};
要本地测试触发器,请运行 zapier invoke
。该命令会询问您要调用的操作。目前我们只有一个触发器 recipe
,因此可以选择它。
$ zapier invoke
? Which action type would you like to invoke? trigger
? Which "trigger" key would you like to invoke? recipe
✔ Invoking triggers.recipe.operation.inputFields
✔ Invoking triggers.recipe.operation.perform
[
{
"id": "1",
"createdAt": 1471984289,
"name": "name 1",
"authorId": 63,
"directions": "directions 1",
"style": "style 1"
},
<omitted...>
]
回顾代码:listRecipes
函数负责 API 操作,包括发出 HTTP 请求并返回解析后的响应数据。
在 JavaScript 中,async
/await
是基于 Promises 的语法糖。请确保在调用异步函数时使用 await
或 .then()
。
listRecipes
函数接收两个参数:z
对象和 bundle
对象。
-
Z 对象 是一组处理 API 的实用工具。在示例中,我们使用
z.request
发出 HTTP 调用。 -
Bundle 对象 包含 API 调用所需的数据,如身份验证凭证或 POST 正文数据。在示例中,未使用 Bundle,因为简单 GET 请求不需要这些。
虽然可以使用其他 Node.js 库实现相同功能,但推荐使用 z
对象,因为这些工具内置了增强 Zapier 体验的功能,如 HTTP 调用日志和错误处理。
在 module.exports
中,我们导出了元数据、listRecipes
函数和样本。Zapier 会使用这些元数据将其暴露给用户。
此外,scaffold
命令还执行了以下操作:
index.js
文件现在包括:
const getRecipe = require('./triggers/recipe');
module.exports = {
// ...
triggers: {
[getRecipe.key]: getRecipe,
},
// ...
};
在 test/triggers 文件夹中,创建了 recipe.test.js
文件:
const App = require("../../index");
const appTester = zapier.createAppTester(App);
// 如果可用,将 .env 文件加载到环境中
zapier.tools.env.inject();
describe("triggers.recipe", () => {
it("should run", async () => {
const bundle = {
inputData: {}
};
const results = await appTester(App.triggers.recipe.operation.perform, bundle);
expect(results).toBeDefined();
// TODO: add more assertions
});
});
运行 zapier test
应能通过测试:
$ zapier test
Validating project locally
No structural errors found during validation routine. This project is structurally sound!
✔ Running integration checks...
23 checks passed
Integration checks passed, no issues found.
Adding /Users/marinahand/.zapierrc to environment as ZAPIER_DEPLOY_KEY...
Running test suite with the following command: npm run --silent test --
PASS test/triggers/recipe.test.js
PASS test/triggers.test.js
(7.52s)
Test Suites: 2 passed, 2 total
Tests: 3 passed, 3 total
Snapshots: 0 total
Time: 9.429s
Ran all test suites.
本示例仅使用一个测试,但您可以在 另一个示例应用 中查看多个测试。
3. 修改一个触发器
要让用户自定义触发的食谱菜式风格,请添加一个输入字段。
在 triggers/recipe.js
中,用以下内容替换文件:
const listRecipes = async (z, bundle) => {
const params = {};
if (bundle.inputData.style) {
params.style = bundle.inputData.style;
}
const requestOptions = {
url: "http://57b20fb546b57d1100a3c405.mockapi.io/api/recipes",
params: params,
};
const response = await z.request(requestOptions);
return response.data;
};
module.exports = {
key: "recipe",
noun: "Recipe",
display: {
label: "New Recipe",
description: "Triggers when a new recipe is created.",
},
operation: {
inputFields: [
{
key: "style",
type: "string",
helpText: "Which styles of cuisine this should trigger on.",
required: false,
},
],
perform: listRecipes,
sample: {
id: 1,
createdAt: 1472069465,
name: "Best Spagetti Ever",
authorId: 1,
directions: "1. Boil Noodles\n2. Serve with sauce",
style: "italian",
},
outputFields: [
{ key: "id", label: "ID" },
{ key: "createdAt", label: "Created At" },
{ key: "name", label: "Name" },
{ key: "directions", label: "Directions" },
{ key: "authorId", label: "Author ID" },
{ key: "style", label: "Style" },
],
},
};
输入字段键 "style"
已添加到:
-
operation
中的inputFields
- 定义在 Zap 编辑器中显示的字段,该字段非必填。 -
listRecipes
函数中 - 使用bundle.inputData.style
提供的风格。
在本地开发中,重新运行 zapier invoke
以验证。指定参数:
$ zapier invoke trigger recipe --inputData '{"style":"style 20"}'
✔ Invoking triggers.recipe.operation.inputFields
✔ Invoking triggers.recipe.operation.perform
[
{
"id": "20",
"createdAt": 1578590011,
"name": "name 20",
"authorId": 90,
"directions": "directions 20",
"style": "style 20"
}
]
调整测试:在 test/triggers 中,替换 recipe.test.js
文件:
const zapier = require("zapier-platform-core");
const App = require("../../index");
const appTester = zapier.createAppTester(App);
describe("triggers", () => {
describe("new recipe trigger", () => {
it("should load recipes", async () => {
const bundle = {
inputData: {
style: "style 2",
},
};
const results = await appTester(App.triggers.recipe.operation.perform, bundle);
expect(results.length).toBeGreaterThan(1);
const firstRecipe = results[0];
expect(firstRecipe.name).toEqual("name 2");
expect(firstRecipe.directions).toEqual("directions 2");
});
it("should load recipes without filters", async () => {
const bundle = {};
const results = await appTester(App.triggers.recipe.operation.perform, bundle);
expect(results.length).toBeGreaterThan(1);
const firstRecipe = results[0];
expect(firstRecipe.name).toEqual("name 1");
expect(firstRecipe.directions).toEqual("directions 1");
});
});
});
运行测试以确认:
zapier test
4. 部署一个集成
将本地应用推送到 Zapier,以便在 Zap 中使用。
您可以管理多个版本,以简化更改和测试。首先推送一个版本。
首次推送时,需要注册应用。运行 zapier register
并提供详细信息,然后使用 zapier push
推送:
$ zapier push
✔ Copying project to temp directory
✔ Installing project dependencies
✔ Applying entry point file
✔ Building app definition.json
✔ Validating project schema and style
✔ Zipping project and dependencies
✔ Testing build
✔ Cleaning up temp directory
✔ Uploading version 1.0.0
Push complete! Built build/build.zip and build/source.zip and uploaded them to Zapier.
登录 Zap 编辑器 创建 Zap。
在触发器步骤中,选择您的应用和“New Recipe”触发器,您会看到定义的标签和描述。
在编辑器中填写“style”字段,运行测试时,listRecipes
函数会执行 API 请求。
查看日志:
$ zapier logs --type http
The logs of your app "Example App" listed below.
┌────────┬────────┬────────────────────────────────────────────────────────┬───────────────┬─────────┬──────────────────────────────────────┬───────────────────────────┐
│ Status │ Method │ URL │ Querystring │ Version │ Step │ Timestamp │
├────────┼────────┼────────────────────────────────────────────────────────┼───────────────┼─────────┼──────────────────────────────────────┼───────────────────────────┤
│ 200 │ GET │ http://57b20fb546b57d1100a3c405.mockapi.io/api/recipes │ style=italian │ 1.0.0 │ a9055e16-fc0d-4fb2-a3e6-9d442d1f70e8 │ 2016-09-13T15:11:30-05:00 │
└────────┴────────┴────────────────────────────────────────────────────────┴───────────────┴─────────┴──────────────────────────────────────┴───────────────────────────┘
Most recent logs near the bottom.
5. 添加身份验证
身份验证对 API 交互至关重要。Zapier 支持多种 方案。本例中,在标头中包含 API 密钥。
示例应用:
- Session Auth
- Digest Auth
在 index.js
中,向 module.exports
添加:
authentication: {
type: 'custom',
fields: [
{
key: 'apiKey',
type: 'string'
}
],
test: async (z, bundle) => {
const response = await z.request('http://57b20fb546b57d1100a3c405.mockapi.io/api/me');
return response.data;
},
},
定义了:
-
fields
:定义身份验证字段,类似于触发器的inputFields
。 -
test
:验证凭证的函数。
在 index.js
中添加辅助函数:
const addApiKeyToHeader = (request, z, bundle) => {
request.headers["My-Auth-Header"] = bundle.authData.apiKey;
return request;
};
并在 module.exports
中添加:
beforeRequest: [
addApiKeyToHeader,
],
测试身份验证:
$ zapier invoke auth start
The .env file does not exist or is empty. You may need to set some environment variables in there if your code uses process.env.
? apiKey | string: mock-api-key
Auth data appended to .env file. Run `zapier invoke auth test` to test it.
$ zapier invoke auth test
✔ Invoking authentication.test
[
{
"id": "1",
"createdAt": 1473801403,
"userName": "userName 1"
}
]
推送更新:
zapier push
在 Zap 中添加帐户并验证日志。
6. 邀请团队成员
共享集成至 开发人员仪表板。
运行:
-
zapier team:add user@example.com admin
-
zapier team:add user@example.com collaborator
7. 与用户共享
运行 zapier users:add user@example.com 1.0.0
。
或者使用链接:运行 zapier users:links
。
8. 修改集成
在新版本中进行更改。
了解更多
需要帮助?联系我们。